package stat

import (
	"context"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"navi-mumbai/common/gensql"
)

var _ UserGameDailyOrderStatModel = (*customUserGameDailyOrderStatModel)(nil)

type (
	// UserGameDailyOrderStatModel is an interface to be customized, add more methods here,
	// and implement the added methods in customUserGameDailyOrderStatModel.
	UserGameDailyOrderStatModel interface {
		userGameDailyOrderStatModel
		SumOrderAmount(ctx context.Context, providerId, gameId int64, start, end int64) (int64, error)
		SumOrderUserCount(ctx context.Context, providerId, gameId int64, start, end int64) (int64, error)
		SumOrderCount(ctx context.Context, providerId, gameId int64, start, end int64) (int64, error)
		SumOrderReturnAmount(ctx context.Context, providerId, gameId int64, start, end int64) (int64, error)
		SumOrderReturnUserCount(ctx context.Context, providerId, gameId int64, start, end int64) (int64, error)
		SumOrderReturnCount(ctx context.Context, providerId, gameId int64, start, end int64) (int64, error)
	}

	customUserGameDailyOrderStatModel struct {
		*defaultUserGameDailyOrderStatModel
		genSql *gensql.GenSql
	}
)

// NewUserGameDailyOrderStatModel returns a model for the database table.
func NewUserGameDailyOrderStatModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) UserGameDailyOrderStatModel {
	return &customUserGameDailyOrderStatModel{
		defaultUserGameDailyOrderStatModel: newUserGameDailyOrderStatModel(conn, c, opts...),
		genSql:                             gensql.NewGenSql(),
	}
}

func (m *customUserGameDailyOrderStatModel) SumOrderAmount(ctx context.Context, providerId, gameId int64, start, end int64) (int64, error) {
	q := fmt.Sprintf("select coalesce(sum(order_amount), 0) from %s ", m.table)
	m.genSql.InitSql(q)

	if start != 0 {
		m.genSql = m.genSql.Where("stat_day >= ?", start)
	}
	if end != 0 {
		m.genSql = m.genSql.Where("stat_day <= ?", end)
	}
	if providerId != 0 {
		m.genSql = m.genSql.Where("provider_id = ?", providerId)
	}
	if gameId != 0 {
		m.genSql = m.genSql.Where("game_id = ?", gameId)
	}
	query, args, err := m.genSql.ToSql()
	if err != nil {
		return 0, err
	}
	var resp int64
	err = m.QueryRowNoCacheCtx(ctx, &resp, query, args...)
	switch err {
	case nil:
		return resp, nil
	default:
		return 0, err
	}
}

func (m *customUserGameDailyOrderStatModel) SumOrderUserCount(ctx context.Context, providerId, gameId int64, start, end int64) (int64, error) {
	q := fmt.Sprintf("select coalesce(sum(order_user_count), 0) from %s ", m.table)
	m.genSql.InitSql(q)
	if start != 0 {
		m.genSql = m.genSql.Where("stat_day >= ?", start)
	}
	if end != 0 {
		m.genSql = m.genSql.Where("stat_day <= ?", end)
	}
	if providerId != 0 {
		m.genSql = m.genSql.Where("provider_id = ?", providerId)
	}
	if gameId != 0 {
		m.genSql = m.genSql.Where("game_id = ?", gameId)
	}
	query, args, err := m.genSql.ToSql()
	if err != nil {
		return 0, err
	}
	var resp int64
	err = m.QueryRowNoCacheCtx(ctx, &resp, query, args...)
	switch err {
	case nil:
		return resp, nil
	default:
		return 0, err
	}
}

func (m *customUserGameDailyOrderStatModel) SumOrderCount(ctx context.Context, providerId, gameId int64, start, end int64) (int64, error) {
	q := fmt.Sprintf("select coalesce(sum(order_count), 0) from %s ", m.table)
	m.genSql.InitSql(q)

	if start != 0 {
		m.genSql = m.genSql.Where("stat_day >= ?", start)
	}
	if end != 0 {
		m.genSql = m.genSql.Where("stat_day <= ?", end)
	}
	if providerId != 0 {
		m.genSql = m.genSql.Where("provider_id = ?", providerId)
	}
	if gameId != 0 {
		m.genSql = m.genSql.Where("game_id = ?", gameId)
	}
	query, args, err := m.genSql.ToSql()
	if err != nil {
		return 0, err
	}
	var resp int64
	err = m.QueryRowNoCacheCtx(ctx, &resp, query, args...)
	switch err {
	case nil:
		return resp, nil
	default:
		return 0, err
	}
}

func (m *customUserGameDailyOrderStatModel) SumOrderReturnAmount(ctx context.Context, providerId, gameId int64, start, end int64) (int64, error) {
	q := fmt.Sprintf("select coalesce(sum(return_amount), 0) from %s ", m.table)
	m.genSql.InitSql(q)
	if start != 0 {
		m.genSql = m.genSql.Where("stat_day >= ?", start)
	}
	if end != 0 {
		m.genSql = m.genSql.Where("stat_day <= ?", end)
	}
	if providerId != 0 {
		m.genSql = m.genSql.Where("provider_id = ?", providerId)
	}
	if gameId != 0 {
		m.genSql = m.genSql.Where("game_id = ?", gameId)
	}
	query, args, err := m.genSql.ToSql()
	if err != nil {
		return 0, err
	}
	var resp int64
	err = m.QueryRowNoCacheCtx(ctx, &resp, query, args...)
	switch err {
	case nil:
		return resp, nil
	default:
		return 0, err
	}
}

func (m *customUserGameDailyOrderStatModel) SumOrderReturnUserCount(ctx context.Context, providerId, gameId int64, start, end int64) (int64, error) {
	q := fmt.Sprintf("select coalesce(sum(return_user_count), 0) from %s ", m.table)
	m.genSql.InitSql(q)
	if start != 0 {
		m.genSql = m.genSql.Where("stat_day >= ?", start)
	}
	if end != 0 {
		m.genSql = m.genSql.Where("stat_day <= ?", end)
	}
	if providerId != 0 {
		m.genSql = m.genSql.Where("provider_id = ?", providerId)
	}
	if gameId != 0 {
		m.genSql = m.genSql.Where("game_id = ?", gameId)
	}
	query, args, err := m.genSql.ToSql()
	if err != nil {
		return 0, err
	}
	var resp int64
	err = m.QueryRowNoCacheCtx(ctx, &resp, query, args...)
	switch err {
	case nil:
		return resp, nil
	default:
		return 0, err
	}
}

func (m *customUserGameDailyOrderStatModel) SumOrderReturnCount(ctx context.Context, providerId, gameId int64, start, end int64) (int64, error) {
	q := fmt.Sprintf("select coalesce(sum(return_count), 0) from %s ", m.table)
	m.genSql.InitSql(q)
	if start != 0 {
		m.genSql = m.genSql.Where("stat_day >= ?", start)
	}
	if end != 0 {
		m.genSql = m.genSql.Where("stat_day <= ?", end)
	}
	if providerId != 0 {
		m.genSql = m.genSql.Where("provider_id = ?", providerId)
	}
	if gameId != 0 {
		m.genSql = m.genSql.Where("game_id = ?", gameId)
	}
	query, args, err := m.genSql.ToSql()
	if err != nil {
		return 0, err
	}
	var resp int64
	err = m.QueryRowNoCacheCtx(ctx, &resp, query, args...)
	switch err {
	case nil:
		return resp, nil
	default:
		return 0, err
	}
}
